/*
  1. @babel/parser: 负责将代码解析为抽象语法树
  2. @babel/traverse: 遍历抽象语法树的工具，我们可以在语法树中解析特定的节点，然后做一些操作，如 ·ImportDeclaration· 
     通过import引入的模块， ·FuncitonDeclaration· 获取函数
  3. @babel/core: 代码转换，如ES6的代码转换为ES5的模式，或者转换JSX语法等等

  此文件的主要作用是解析模块依赖，转换代码  获取单个文件依赖
*/
const fs = require('fs');
const path = require('path');
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const babel = require('@babel/core');

const exportDependencies = (filename) => {
  const content = fs.readFileSync(filename, 'utf-8');
  // 转换Ast
  const ast = parser.parse(content, {
    sourceType: 'module',
  });

  const dependencies = {};
  // 遍历抽象语法树 TraverseOptions<babel.types.Node>
  traverse(ast, {
    //调用ImportDeclaration获取通过import引入的模块
    ImportDeclaration({ node }) {
      const dirname = path.dirname(filename);
      const newFile = './' + path.join(dirname, node.source.value);
      //保存所依赖的模块
      dependencies[node.source.value] = newFile;
    },
  });

  //通过@babel/core和@babel/preset-env进行代码的转换
  const { code } = babel.transformFromAst(ast, null, {
    presets: ['@babel/preset-env'],
  });

  return {
    filename, //该文件名
    dependencies, //该文件所依赖的模块集合(键值对存储)
    code, //转换后的代码
  };
};

module.exports = exportDependencies;
